import stackless
import socket
import select
import struct
import thread
import random
import hmac
import world
from sglibrary import Vector

import time # Remove??

def game_server_stackless(address, port, world_chan):
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.setblocking(0)
    sock.bind((address, port))
    poller = select.poll()
    poller.register(sock, select.POLLIN)
    while True:
        if poller.poll(0):
            data, address = sock.recvfrom(1024)
            world_chan.send(("DATA", address, data))
        stackless.schedule()

def game_receiver(address, port, world_chan):
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind((address, port))
    while True:
        data, address = sock.recvfrom(1024)
        print "received", data
        world_chan.send(("DATA", address, data))

def game_sender(address, port, data):
    print "sending", data
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind((address, 23854)) ## CHANGE PORT
    sock.send_all(data)
    sock.close()

def get_connections_stackless(address, port, world_chan):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind((address, port))
    sock.listen(5)
    #stackless.tasklet(logon)(world_chan, *sock.accept())
    sock.setblocking(0)
    poller = select.poll()
    poller.register(sock)
    while True:
        if poller.poll(0):
            print "connection made!"
            stackless.tasklet(logon)(world_chan, *sock.accept())
        stackless.schedule()

def get_connections(address, port, world_chan):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind((address, port))
    sock.listen(5)
    while True:
        logon(world_chan, *sock.accept())
    
def recv_data(sock):
    print "receiving"
    sock.setblocking(0)
    poller = select.poll()
    poller.register(sock, select.POLLIN)
    while True:
        if poller.poll(0):
            return sock.recv(1024)
        stackless.schedule()

def send_data(sock, data):
    sock.setblocking(0)
    poller = select.poll()
    poller.register(sock, select.POLLOUT)
    while True:
        if poller.poll(0):
            sent = sock.send(data)
            if sent == len(data):
                break
            else:
                data = data[sent:]
        stackless.schedule()

def logon(world_chan, sock, address):
    username = recv_data(sock)
    print username
    key = "Hadoken" #open("%s_key" % username).read()
    clear_text = str(random.random())
    print "sending", clear_text
    send_data(sock, clear_text)
    print "sent"
    cipher_text = recv_data(sock)
    check_text = hmac.new(key, clear_text).hexdigest()
    print check_text, "==", cipher_text
    if cipher_text == check_text:
        stackless.tasklet(world.Player)(Vector(0,0,0), Vector(0,1,0),
                                        world_chan, address)
        send_data(sock, "Authenticated")
    else:
        send_data(sock, "didn't work!")
                

def receive(channel):
    while 1:
        data = channel.receive()#[2]
        print data, len(data)
    #print struct.unpack("B24s", data)

def wait():
    while 1:
        time.sleep(1)
        stackless.schedule()

if __name__ == "__main__":
    #test(socket.SOCK_DGRAM, 'localhost', 45988)
    channel = stackless.channel()
    #GameServer(socket.SOCK_DGRAM, 'localhost', 45988, channel)
    #stackless.tasklet(wait)()
    #stackless.tasklet(login_server)("localhost", , channel)
    thread.start_new_thread(get_connections, ("localhost", 45988, channel))
    thread.start_new_thread(game_receiver, ("localhost", 45989, channel))
    #stackless.tasklet(get_connections)("localhost", 26734, channel)
    #stackless.tasklet(game_server)("localhost", 45988, channel)
    #stackless.tasklet(receive)(channel)
    #stackless.tasklet(receive)(channel)
    #stackless.run()
